/*! \file tvMosaicParam.h
 *      \brief Defines the variables and methods to reconstruct TissueVision
 *       STP image collected on TissueCyte 1000
*/
#include <iostream>
#include <string>
#include <vector>
#include <itkImage.h>
#include <itkImageFileReader.h>
#include <itkImageFileWriter.h>
#include <itkCastImageFilter.h>

typedef float AverageTilePixelType;
typedef itk::Image<AverageTilePixelType,2> AverageTileType;
typedef unsigned short TilePixelType;
typedef itk::Image<TilePixelType,2> TileImageType;
/*
typedef unsigned short TissueVisionPixelType;
typedef itk::Image<TissueVisionPixelType,2> TissueVisionImageType;
typedef itk::ImageFileReader<TissueVisionImageType> RawReaderType;

typedef itk::Image<TilePixelType,2> AverageImageOutputType;
typedef itk::ImageFileReader<TileImageType> TileImageReaderType;
typedef itk::ImageFileWriter<TileImageType> TileWriterType;

typedef float AverageTilePixelType;
typedef itk::Image<AverageTilePixelType,2> AverageTileType;
typedef itk::ImageFileWriter<AverageImageOutputType> AverageImageWriterType;

typedef itk::CastImageFilter<TileImageType,AverageTileType> CastFilterType;            
typedef itk::CastImageFilter<AverageTileType,AverageTileType> NullFilterType;
typedef itk::CastImageFilter<AverageTileType,TileImageType> AverageImageOutputFilterType;

enum imageFormat {BIN_FORMAT = 0, TIF_FORMAT = 1};
*/

/*! \mainpage
 *
 * \image html STP.gif
 * \section intro_sec Introduction
 *
 * This documentation explains the class heirarchy, variable and methods
 *
 * \section install_sec Installation
 *
 * The build and installation on the software is described in the project wiki page http://code.google.com/p/fluo-mouse-brain/wiki/CompileCode
 *  
 * \section source_sec Source
 *
 * The details to checkout the source code can be found at the google code SVN at http://code.google.com/p/fluo-mouse-brain/source/checkout
 *
 * \section related_pages Related pages
 * 
 * http://www.nature.com/nmeth/journal/v9/n3/full/nmeth.1854.html
 *
 * http://www.cshl.edu/Faculty/osten-pavel.html
 */

using namespace std;
/*! STP dataclass specific for Tissue Vision class */
/*! \class tvMosaicParam
 *      \brief Defines the variables and methods to reconstruct TissueVision
 *       STP image collected on TissueCyte 1000
*/
class tvMosaicParam {
public:
  int rows; /**< Number of pixel rows in a tile */
  int columns; /**< Number of pixel columns in a tile */
  int layers; /**< Number of optical layers in a histological section */
  float xres;
  float yres;
  float zres;
  int mrows; /**< Number of tile rows on the image mosiac*/
  int mcolumns; /**< Number of tile columns on the image mosiac*/
  int mrowres;
  int mcolumnres;
  int sections; /**< Number of histological sections on the image mosiac*/
  int sectionres;
  int channels; /**< Number of channels imaged*/
  int Pixrestime;
  float xoverlap; /**< Percentage of overlap in tiles along X-axis*/
  float yoverlap; /**< Percentage of overlap in tiles along Y-axis*/
  float zoverlap; /**< Percentage of overlap in tiles along Z-axis*/
  int normflag;
  int Normimage;
  int startnum; /**< Starting number of the image series*/
  int excwavelength; /**< LASER's excitation wave-length in nanometers*/
  int excpower; /**< LASER's excetation power in milliWatts*/
  int numfoci;
  string objective;
  string basefilename; /**< */
  string fSuffix; /**< */
  string fPrefix; /**< */
  string sample; /**< */
  string acqDate; /**< */
  string comments; /**< */

  // TV dataset settings
  string tvParamFileName; /**< Parameter file name with full file location*/
  string tvDataHome; /**< */
  string tvDataProcessingHome; /**< */
  string tvDataPrefix; /**< */
  string tvOutputImageFormat; /**< */
  string tvOutputDirectory; /**< */
  string tvCorrectedTileOutputDirectory; /**< */
  string tvInputDirectory; /**< */
  string tvStitchedImageDirectory; /**< */
  string tvWarpedImageDirectory; /**< */
  string tvAverageImageDirectory; /**< */
  string tvAverageImageFileName; /**< */

  unsigned short croppedTileSizeX; /**< */
  unsigned short croppedTileSizeY; /**< */
  unsigned short croppedStartX; /**< */
  unsigned short croppedStartY; /**< */

  // Running parameters
  bool doConvertTiles; /**< */
  bool doCalculateCorrectionTile; /**< */
  bool doIlluminationCorrection; /**< */
  bool doStitching; /**< */
  bool doImageResize; /**< */
  void SetConvertTiles(char* sConvertTiles);
  void SetCalculateCorrectionTile(char* sCalculateCorrectionTile);
  void SetIlluminationCorrection(char* sIlluminationCorrection);
  void SetStitching(char* sStitching);
  void SetImageResize(char* sImageResize);
  void SetConvertTiles(bool bConvertTiles);
  void SetCalculateCorrectionTile(bool bCalculateCorrectionTile);
  void SetIlluminationCorrection(bool bIlluminationCorrection);
  void SetStitching(bool bStitching);
  void SetImageResize(bool bImageResize);

  // Calulated variables
  vector<int> XPos;
  vector<int> YPos;
  vector<int> tileX;
  vector<int> tileY;
  vector<int> tileZ;
  vector<int> layerID;
  vector<string> binaryFileName;
  vector<string> imageFileName;
  vector<string> stitchedFileName;

  // Class methods
  tvMosaicParam ();
  void SetXOverlap (float xOverlap);
  void SetYOverlap (float yOverlap);
  void SetZOverlap (float zOverlap);
  float GetXOverlap ();
  float GetYOverlap ();
  float GetZOverlap ();

  void SetParamFileName(char* paramFileName);
  void SetDataHome(char* dataSetHomeDirectory);
  void SetDataProcessingHome(char *dataSetProcessingHome);
  void SetDataPrefix(char* dataSetPrefix);
  void SetOutputImageFormat(char* outputImageFormat);
  void GenerateCorrectedTileDirectory();
  void GenerateInputDirectory();
  void GenerateOutputDirectory();
  void GenerateStitchedDirectory();
  void GenerateWarpingDirectory();
  void GenerateCorrectionParameters ();

  void setDefaultParameters();
  void initializeDataset();
  void initializeExampleDataset();
  int readMosaicParamFile();
  int writeImageTiles();
  int createAverageTile();
  int writeCorrectedImageTiles();
  void writeStitchedImages();
  void writeAllStitchedImages();
  void writeStitchedImage(unsigned int sectionID, unsigned int layerID);
  void writeStitchedImageITK(unsigned int sectionID, unsigned int layerID);
  string getStitchedImageFileName (unsigned int sectionID, unsigned int layerID);
  void writeScaledImage (float scaleFactor);
  void runReconstructionPipeline();
  //template <class TileType, class TilePixelType> void CreateConstantImage(TileType::Pointer image, TilePixelType pixelValue);

  void CreateConstantImage(AverageTileType::Pointer image, AverageTilePixelType pixelValue);
  void CreateConstantImage(TileImageType::Pointer image, TilePixelType pixelValue);

}
;
